package org.gpp.proj1.util;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import com.jme.bounding.BoundingBox;
import com.jme.math.Vector3f;
import com.jme.scene.TriMesh;
import com.jme.util.geom.BufferUtils;
 
/**
 * @author Mike Stoddart (stodge at users.sourceforge.net)
 */
public class GeometryBatch extends TriMesh {
    
	private static final long serialVersionUID = 8675431614619207358L;

	/** Creates a new instance of GeometryBatch */
    public GeometryBatch() {
        FloatBuffer vertices;
        FloatBuffer normal;
        FloatBuffer color;
        FloatBuffer texture;
        IntBuffer indices;
 
        vertices = BufferUtils.createFloatBuffer(0);
        normal = BufferUtils.createFloatBuffer(0);
        color = BufferUtils.createColorBuffer(0);
        texture = BufferUtils.createFloatBuffer(0);
        indices = BufferUtils.createIntBuffer(0);
        reconstruct(vertices, normal, color, texture, indices);
 
        this.setModelBound(new BoundingBox());
        updateModelBound();
    }
    
    public static GeometryBatch create(String name, TriMesh mesh)
    {
        return new GeometryBatch(name, mesh);
    }
    
    /** Creates a new instance of GeometryBatch */
    public GeometryBatch(String name, TriMesh mesh) {
        super(name);
        
        
        FloatBuffer vertices = BufferUtils.clone(mesh.getVertexBuffer());
        FloatBuffer normal = BufferUtils.clone(mesh.getNormalBuffer());
        FloatBuffer color = BufferUtils.clone(mesh.getColorBuffer());
        FloatBuffer texture = BufferUtils.clone(mesh.getTextureBuffer());
        IntBuffer indices = BufferUtils.clone(mesh.getIndexBuffer());
 
        reconstruct(vertices, normal, color, texture, indices);
 
        this.setModelBound(new BoundingBox());
        updateModelBound();
    }
    
    public static void dumpFloatBuffer(FloatBuffer buff, String title)
    {
        System.out.println("********** Start FloatBuffer " + title);
        int cap = buff.capacity();
        buff.rewind();
        
        System.out.println();
        
        for (int ii=0; ii<cap; ii++)
        {
            System.out.println(buff.get());
        }
        System.out.println();
        System.out.println("********** End FloatBuffer **********");
 
        buff.rewind();
    }
    
    public static void dumpIntBuffer(IntBuffer buff, String title)
    {
        System.out.println("********** Start IntBuffer " + title);
        int cap = buff.capacity();
        buff.rewind();
        
        System.out.println();
        
        for (int ii=0; ii<cap; ii++)
        {
            System.out.println(Integer.toString(ii) + " " + Integer.toString(buff.get()));
        }
        System.out.println();
        System.out.println("********** End IntBuffer **********");
        
        buff.rewind();
    }
 
    public void addGeometry(TriMesh mesh, Vector3f translation)
    {
        // Append the indices.
        int total = this.getIndexBuffer().capacity() + mesh.getIndexBuffer().capacity();
        IntBuffer indices = BufferUtils.createIntBuffer(total);
        IntBuffer buff = this.getIndexBuffer();
        buff.rewind();
        indices.put(buff);       
 
        int extra = this.getVertexBuffer().capacity() / 3;
        buff = mesh.getIndexBuffer();
        buff.rewind();
        for (int ii=0; ii<buff.capacity(); ii++)
        {
            indices.put(buff.get() + extra);
        }
        
        // Append the normals.
        total = this.getNormalBuffer().capacity() + mesh.getNormalBuffer().capacity();
        FloatBuffer normal = BufferUtils.createFloatBuffer(total);
        FloatBuffer buff2 = this.getNormalBuffer();
        buff2.rewind();
        normal.put(buff2);
        
        buff2 = mesh.getNormalBuffer();
        buff2.rewind();
        normal.put(buff2);
        
        // Append the texture coords.
        total = this.getTextureBuffer().capacity() +
		mesh.getTextureBuffer().capacity();
        FloatBuffer texture = BufferUtils.createFloatBuffer(total);
        buff2 = this.getTextureBuffer();
        buff2.rewind();
        texture.put(buff2);
        
        buff2 = mesh.getTextureBuffer();
        buff2.rewind();
        texture.put(buff2);
        
        // Take a temp copy of the vertices and translate them.
        FloatBuffer temp = BufferUtils.clone(mesh.getVertexBuffer());
        int count = temp.capacity() / 3;
        for (int ii=0; ii<count; ii++)
        {
            BufferUtils.addInBuffer(translation, temp, ii);
        }
        temp.rewind();
 
        // Append the vertices.
        total = this.getVertexBuffer().capacity() + mesh.getVertexBuffer().capacity();
        FloatBuffer vertices = BufferUtils.createFloatBuffer(total);
        buff2 = this.getVertexBuffer();
        buff2.rewind();
        
        vertices.put(buff2);
        vertices.put(temp);
        
        // Append the colour.
        FloatBuffer color = null;
        if (this.getColorBuffer() != null && mesh.getColorBuffer() == null)
        {
            color = BufferUtils.clone(this.getColorBuffer());
        }
        else if (mesh.getColorBuffer() != null && this.getColorBuffer() == null)
        {
            color = BufferUtils.clone(mesh.getColorBuffer());
        }
        else if (mesh.getColorBuffer() != null && this.getColorBuffer() != null)
        {
                total = this.getColorBuffer().capacity() + mesh.getColorBuffer().capacity();
                color = BufferUtils.createColorBuffer(total);
                buff2 = this.getColorBuffer();
                buff2.rewind();
                color.put(buff2);
                
                buff2 = mesh.getColorBuffer();
                buff2.rewind();
                color.put(buff2);
        }
 
        reconstruct(vertices, normal, color, texture, indices);
        
        updateModelBound();
    }
    
    public String toString()
    {
        return super.toString();
    }
}